#include "QMeter.h"
#include "ui_QMeter.h"
#include <QColor>
#include <QFont>
#include <QtDebug>

QMeter::QMeter(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Speedometer)
{
    ui->setupUi(this);
    m_value = 0;
    m_rangeMax = 60;
    m_rangeMin = -60;
    m_scaleMajor = 4;
    m_scaleMinor = 2;
    m_angleRange = 120;
    m_scaleText = m_scaleMajor;
    m_meterName = QString("转向角度\n(°)");
    m_textFont.setPixelSize(10);
    this->update();
}

QMeter::~QMeter()
{
    delete ui;
}

void QMeter::paintEvent(QPaintEvent *)
{
    _width = this->width();
    _height = this->height();
    int side = qMin(_width, _height);
    m_radius = side/2;

    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing|QPainter::HighQualityAntialiasing);

    painter.translate(_width/2, _height/2);//转换坐标原点
    painter.scale(side/m_radius/2, side/m_radius/2);//缩放
//    m_radius = side/2;

    drawBorder(&painter);
    drawBg(&painter);
    drawScale(&painter);
    drawPointer(&painter);
    drawMeterName(&painter);
}

/**
 * @brief QMeter::polarCoord    极坐标转直角坐标
 * @param r                     半径
 * @param ang                   角度
 * @return                      直角坐标
 */
QPointF QMeter::polarCoord(qreal r, qreal ang)
{
    QPointF Tmp;
    qreal PI=3.141592653589;
    qreal arc = qreal(ang/180*PI);
    Tmp.setX(r*qCos(arc));
    Tmp.setY(r*qSin(arc));
    return Tmp;
}

/**
 * @brief QMeter::drawBorder    绘制边框
 * @param painter
 */
void QMeter::drawBorder(QPainter *painter)
{
    int radius = m_radius;
    QColor borderOutColorStart = QColor(14,14,14);
    QColor borderOutColorEnd = QColor(227,225,226);

    painter->save();
    painter->setPen(Qt::NoPen);
    QLinearGradient borderGradient(-radius, 0, radius, 0);
    borderGradient.setColorAt(0, borderOutColorStart);
    borderGradient.setColorAt(0.38, borderOutColorEnd);
    borderGradient.setColorAt(0.62, borderOutColorEnd);
    borderGradient.setColorAt(1, borderOutColorStart);

    painter->setBrush(borderGradient);
    painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->restore();
}

void QMeter::drawBg(QPainter *painter)
{
    int radius = m_radius-8;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(QBrush(QGradient(QGradient::ViciousStance)));
    painter->drawEllipse(-radius,-radius,radius * 2,radius * 2);
    painter->restore();
}

void QMeter::drawScale(QPainter *painter)
{
//    int rangeMax = 200;
//    int rangeMin = 0;
//    int scaleMajor = 20;
//    int scaleMinor = 2;//主刻度的分划数量
//    qreal angleRange = 280;
    int radius = m_radius - 12;
    painter->save();
    //主刻度
    QColor scaleColor = QColor(239,146,51);
    QPen scalePen;
    scalePen.setWidth(1);
    scalePen.setColor(scaleColor);
    painter->setPen(scalePen);


    qreal rotate_step = m_angleRange/(m_scaleMajor * m_scaleMinor);
    painter->rotate(-qreal(m_angleRange / 2));//旋转至0刻度
    int speed = m_rangeMin;
    int speed_step = (m_rangeMax-m_rangeMin) / m_scaleText;

    for (int i = 0; i <= m_scaleMajor * m_scaleMinor; ++i)
    {
        if(i % m_scaleMinor)//副刻度
        {
            painter->drawLine(0,-radius,0,-(radius-3));
        }
        else//主刻度
        {
            painter->drawLine(0,-radius,0,-(radius-5));
        }
        painter->rotate(rotate_step);
    }

    painter->resetTransform();
    painter->translate(_width/2, _height/2);//转换坐标原点


    qreal text_ang = -90 - qreal(m_angleRange / 2);
    painter->setFont(m_textFont);
    QPointF text_pos;
    rotate_step = m_angleRange/m_scaleText;
    int text_radius = radius - 12;
    text_pos = polarCoord(text_radius - 20, text_ang);
//    painter->drawPoint(text_pos);
#if 1
    for(int i=0; i<=m_scaleText; i++)
    {
        QRectF boundingRect;
        text_pos = polarCoord(text_radius, text_ang);
        QRectF text_rect = QRect(text_pos.x()-12,text_pos.y()-8,26,16);
        painter->drawText(text_rect,Qt::AlignHCenter|Qt::AlignTop, QString::number(speed),&boundingRect);
        speed += speed_step;
        text_ang += rotate_step;
    }
#endif
    painter->restore();
}

void QMeter::drawPointer(QPainter *painter)
{
    static const QVector<QPoint>speedHand = {
        QPoint(3, 0),
        QPoint(-3, 0),
        QPoint(0, -(m_radius*0.7))
    };

    painter->save();
    QColor pointerColor = QColor(239,146,51);
    QPen scalePen;
    scalePen.setWidth(2);
    scalePen.setColor(pointerColor);
    painter->setPen(scalePen);

    painter->drawPoint(0,0);
    QPainterPath pointerPath;
    pointerPath.setFillRule(Qt::WindingFill);
    pointerPath.addPolygon(QPolygon(speedHand));
    pointerPath.addEllipse(QPointF(0,0),3,3);
    qreal rotateVal = (m_value - qreal(m_rangeMax + m_rangeMin) / 2) * m_angleRange/(m_rangeMax-m_rangeMin) ;
    painter->rotate(rotateVal);
    painter->fillPath(pointerPath, QBrush(pointerColor));

    painter->restore();
}

void QMeter::drawMeterName(QPainter *painter)
{
    painter->save();
    painter->setFont(m_textFont);
    QColor scaleColor = QColor(239,146,51);
    QPen scalePen;
    scalePen.setWidth(2);
    scalePen.setColor(scaleColor);
    painter->setPen(scalePen);

    painter->drawText(-50, m_radius/3, 100, 30, Qt::AlignHCenter|Qt::AlignVCenter, m_meterName);
    painter->restore();
}

int QMeter::value() const
{
//    qDebug()<<m_speed;
    return m_value;
}

int QMeter::rangeMax() const
{
    return m_rangeMax;
}

int QMeter::rangeMin() const
{
    return m_rangeMin;
}

int QMeter::scaleMajor() const
{
    return m_scaleMajor;
}

int QMeter::scaleMinor() const
{
    return m_scaleMinor;
}

qreal QMeter::angleRange() const
{
    return m_angleRange;
}

int QMeter::scaleText() const
{
    return m_scaleText;
}

QString QMeter::meterName() const
{
    return m_meterName;
}

int QMeter::radius() const
{
    return m_radius;
}

bool QMeter::autoResize() const
{
    return m_autoResize;
}

QFont QMeter::TextFont() const
{
    return m_textFont;
}

void QMeter::setValue(int val)
{
    m_value = val;
    this->update();
}

void QMeter::setRangeMax(int rangeMax)
{
    m_rangeMax = rangeMax;
    this->update();
}

void QMeter::setRangeMin(int rangeMin)
{
    m_rangeMin = rangeMin;
    this->update();
}

void QMeter::setScaleMajor(int scaleMajor)
{
    m_scaleMajor = scaleMajor;
    this->update();
}

void QMeter::setScaleMinor(int scaleMinor)
{
    m_scaleMinor = scaleMinor;
    this->update();
}

void QMeter::setAngleRange(qreal angleRange)
{
    m_angleRange = angleRange;
    this->update();
}

void QMeter::setScaleText(int scaleText)
{
    m_scaleText = scaleText;
    this->update();
}

void QMeter::setMeterName(QString meterName)
{
    m_meterName = meterName;
    this->update();
}

void QMeter::setRadius(int radius)
{
    m_radius = radius;
    this->update();
}

void QMeter::setAutoResize(bool autoResize)
{
    m_autoResize = autoResize;
    this->update();
}

void QMeter::setTextFont(QFont textFont)
{
    m_textFont = textFont;
    this->update();
}
